<?php


namespace app\model;


use app\common\constants\ReturnCodeConstants;
use app\common\exception\UpdateFailException;
use app\common\util\Response;
use think\Model;

class BaseModel extends Model
{
    /**
     * @var string 主键id字段名
     */
    public $idFieldName = 'id';

    /**
     * @var string 状态字段名
     */
    protected $statusFieldName = 'status';
    /**
     * @var string 判断删除的字段名
     */
    protected $deleteFieldName = 'is_del';

    /**
     * 获取数据列表
     * @param array $where 查询条件
     * @param string $field 查询字段
     * @param string $sort 排序
     * @param bool $isPage 是否分页
     * @return array
     */
    public function getList(array $where = [], string $field = '*', string $sort = '', bool $isPage = false): array
    {
        //排序，为空则默认根据id倒叙
        $sort = $sort === '' ? $this->idFieldName . ' desc' : $sort;
        //如果删除字段不为空，不查询已删除的数据
        $where = $this->mergeDeleteFieldToWhere($where);

        //不分页直接查询返回
        if ($isPage === false) {
            return $this->where($where)->field($field)->order($sort)->select()->toArray();
        }
        //自动获取分页参数
        $get = request()->get('', null, null);
        $page = isset($get['page']) && !empty($get['page']) ? $get['page'] : 1;
        $limit = isset($get['limit']) && !empty($get['limit']) ? $get['limit'] : 15;

        //数据总量统计
        $count = $this->where($where)->count();
        //数据集
        $data = $this->where($where)->page($page, $limit)->order($sort)->field($field)->select()->toArray();
        return Response::successReturn(ReturnCodeConstants::SUCCESS_CODE, '', $data, $count);
    }

    /**
     * 根据主键id获取单条数据
     * @param int $id id
     * @param string $field 要查询的列
     * @param bool $emptyException 为空时是否报错
     * @return array|Model
     */
    public function getInfoById(int $id, string $field = '*', bool $emptyException = false)
    {
        $where = $this->mergeDeleteFieldToWhere([$this->idFieldName => $id]);
        $data = $this->where($where)->field($field)->failException($emptyException)->find();
        return empty($data) ? [] : $data;
    }

    /**
     * 根据查询条件获取单条数据
     * @param array $where 条件数组
     * @param string $field 要查询的列
     * @param bool $emptyException 为空时是否报错
     * @return array|Model
     */
    public function getInfo(array $where, string $field = '*', bool $emptyException = false)
    {
        $where = $this->mergeDeleteFieldToWhere($where);
        $data = $this->where($where)->field($field)->failException($emptyException)->find();
        return empty($data) ? [] : $data;
    }

    /**
     * 根据查询条件获取单个字段数据
     * @param array $where
     * @param string $field
     * @return string|Model
     */
    public function getOneFieldValue(array $where, string $field)
    {
        $where = $this->mergeDeleteFieldToWhere($where);
        return $this->where($where)->value($field);
    }

    /**
     * 更新数据，要有影响行数
     * @param array $where 条件
     * @param array $data 更新数据
     * @return integer 影响行数
     */
    public function updateNeedAffectedRows(array $where, array $data)
    {
        $where = $this->mergeDeleteFieldToWhere($where);
        $this->update($data, $where);
        if ($this->getNumRows() === 0) {
            throw new UpdateFailException();
        }
        return $this->getNumRows();
    }

    /**
     * 更新状态
     * @param int $id id
     * @param int $newStatus 新状态
     * @param null $oldStatus 旧状态
     * @param array $uData 需要另外更新的数据
     * @param string $fieldName 更新状态的字段
     * @return integer|false
     */
    public function updateStatus(int $id, int $newStatus, $oldStatus = null, array $uData = [], string $fieldName = '')
    {
        $where = [$this->idFieldName => $id];
        //是否自定义状态字段名
        $fieldName = $fieldName === '' ? $this->statusFieldName : $fieldName;
        //如果有旧状态
        if ($oldStatus !== null) {
            $where[$fieldName] = $oldStatus;
        }
        //合并删除判断
        $where = $this->mergeDeleteFieldToWhere($where);
        $uData[$fieldName] = $newStatus;
        return $this->updateNeedAffectedRows($where, $uData);
    }

    /**
     * 根据id更新数据
     * @param int $id ID
     * @param array $uData 更新数据
     * @return false|int
     */
    public function updateDataById(int $id, array $uData)
    {
        $where = $this->mergeDeleteFieldToWhere([$this->idFieldName => $id]);
        return $this->updateNeedAffectedRows($where, $uData);
    }

    /**
     * 条件加上删除
     * @param array $where
     * @return array
     */
    protected function mergeDeleteFieldToWhere(array $where)
    {
        return empty($this->deleteFieldName) ? $where : array_merge($where, [$this->deleteFieldName => 0]);
    }

    /**
     * @param int $id
     * @param array $where
     * @param array $uData
     * @return int
     * @throws UpdateFailException
     */
    public function softDelete(int $id, array $where = [], array $uData = [])
    {
        $where[$this->idFieldName] = $id;
        $where = $this->mergeDeleteFieldToWhere($where);
        $uData[$this->deleteFieldName] = 1;
        return $this->updateNeedAffectedRows($where, $uData);
    }
}